﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace FrogEngine
{
	public abstract class BaseCamera : GameEntityBase, IOriented3DGameEntity, ICamera
	{
		public BaseCamera(IEngine engine)
			: base(engine)
		{
			Position = Vector3.Zero;
			Velocity = Vector3.Zero;
			Forward = Vector3.Forward;
			Right = Vector3.Right;
			Up = Vector3.Up;
			Fov = MathHelper.PiOver4;
			Force = Vector3.Zero;
			Mass = 100f;
			LookSensitivity = 1;
		}

		public BaseCamera(IEngine engine, Vector3 position, Matrix orientation)
			: base(engine)
		{
			Position = position;
			Velocity = Vector3.Zero;
			Forward = orientation.Forward;
			Right = orientation.Right;
			Up = orientation.Up;
			Fov = MathHelper.PiOver4;
			Mass = 100f;
			LookSensitivity = 1;
		}

		public Vector3 Position { get; set; }

		public Vector3 Velocity { get; set; }

		public Vector3 Force { get; set; }

		public float Mass { get; set; }

		public Vector3 Forward { get; set; }

		public Vector3 Right { get; set; }

		public Vector3 Up { get; set; }

		public float Fov { get; set; }

		public float AspectRatio { get; set; }

		public float NearPlane { get; set; }

		public float FarPlane { get; set; }

		public int LookSensitivity { get; set; }

		public Matrix World { get; set; }

		public Matrix View { get; protected set; }

		public Matrix Projection { get; protected set; }

		public bool IgnoreInput { get; set; }

		public virtual void Update(GameTime gameTime)
		{
			float dt = (float)gameTime.ElapsedGameTime.TotalMilliseconds;

			// F = MA
			Vector3 acceleration = Force / Mass;

			Velocity += acceleration * dt;
			Position += Velocity * dt;

			View = Matrix.CreateLookAt(Position, Position + Forward, Up);
			Projection = Matrix.CreatePerspectiveFieldOfView(Fov, AspectRatio, NearPlane, FarPlane);
		}

		public virtual void HandleInput(GameTime gameTime, PlayerIndex index, KeyboardState currentState, KeyboardState previousState)
		{
		}

		public PlayerIndex PlayerIndex { get; set; }

		public virtual void HandleInput(GameTime gameTime, MouseState currentState, MouseState prevState, float dx, float dy)
		{
		}

		public virtual void HandleInput(GameTime gameTime, PlayerIndex index, GamePadState currentState, GamePadState previousState)
		{
		}
	}
}
